﻿using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using SGLisp;
public class TriggerInstance 
{
    public SGTrigger trigger;
    public bool IsRunning;
    public int CurActioni;
    public bool IsWaitAction;
    public List<BaseAction> ActionNodes;

    public Context ClojureContext; 
    public TriggerInstance(SGTrigger trigger) 
    {
        this.trigger = trigger;
        this.ClojureContext =trigger.ClojureContext.Copy();
        //Clone Actions
        this.ActionNodes = new List<BaseAction>();
        for (int i = 0; i < trigger.ActionNodes.Count;i++)
        {
            if (trigger.ActionNodes[i].Typ == BaseAction.ActionType.NonBlock)
            {
                this.ActionNodes.Add(trigger.ActionNodes[i]);
            }
            else 
            {
                 ListNode lstNode =  (ListNode)trigger.ActionNodes[i].ActionNode;
                 SymbolNode actionNameNode = ((SymbolNode)lstNode.nodes.First.Value);
                 BlockAction blockAction = (BlockAction)System.Activator.CreateInstance(System.Type.GetType(actionNameNode.Val + "Action"));
                 blockAction.Typ = BaseAction.ActionType.Block;
                 blockAction.ActionNode = lstNode; 
                 blockAction.OnLoad(new List<ASTNode>(lstNode.nodes)); 
                 this.ActionNodes.Add(blockAction);
            }
        }
    }

    public void Run() 
    {
        this.IsRunning = true;
        this.CurActioni = 0;
        this.IsWaitAction = false;
    }

    public void Update() 
    {
        if (IsRunning == false)
        {
            return;
        }
        BaseAction action = this.ActionNodes[CurActioni];
        while (CurActioni < this.ActionNodes.Count && !IsWaitAction)
        {
            if (action.Typ == BaseAction.ActionType.Block)
            {
                IsWaitAction = true;
                action.OnExec(this.ClojureContext);
            }
            else
            {
                IsWaitAction = false;
                action.OnExec(this.ClojureContext);
                CurActioni++;
                if (CurActioni == this.ActionNodes.Count)
                {
                    this.IsRunning = false;
                    return;
                }
                action = this.ActionNodes[CurActioni];
            }
        }
        if (IsWaitAction && action != null)
        {
            BlockAction blockAction = (BlockAction)action;
            blockAction.Update();
            if (blockAction.IsFinish)
            {
                IsWaitAction = false;
                CurActioni++;
            }
        }
        if (CurActioni == this.ActionNodes.Count)
        {
            this.IsRunning = false;
        }
    }
}
